# -*- coding: utf-8 -*-
# @Time    : 2019/10/25 14:26
# @Author  : LiHaowen
# @Email   : lihaowen2017@163.com
# @File    : concurrent_futures.py
from concurrent.futures import ThreadPoolExecutor, as_completed, wait, FIRST_COMPLETED
from concurrent.futures import Future

# 未来对象；task的返回容器，存放的是task的执行结果执行状况
# 如何更新状况，何时更新状况

# 线程池 使用的原因
# 需求; 主线程中获取某一个线程的状态或者某一个任务的状态，以及返回值
# 当一个线程完成的时候我们主线程能立即知道
# futures可以让多线程和多进程编码接口一致
import time
from queue import Queue


def get_html(times):
    time.sleep(times)
    print(f"get page {times} success")
    return times


executor = ThreadPoolExecutor(max_workers=2)

# 获取已经成功的task的返回
urls = [3, 2, 4]

# 动态获取所有任务，进行执行
all_task = [executor.submit(get_html, (url)) for url in urls]
print(type(all_task[0]))  # submit提交线程池后返回一个future对象
wait(all_task, return_when=FIRST_COMPLETED)  # 阻塞主线程， 第一个子线程执行完就执行主线程
print("main")
# for future in as_completed(all_task):  # 遍历已经成功的task
#     data = future.result()
#     print(f"get {data} page success")

# 通过executor的map获取已经完成的task的值
# 返回结果的顺序与传入的顺序一致
# for data in executor.map(get_html, urls):
#     print(f"get {data} page success")

# 单步穷举范例

# 通过submit函数提交执行的函数到线程池中, submit 是非阻塞的立即返回
# task1 = executor.submit(get_html, (3))
# task2 = executor.submit(get_html, (2))

# done方法用于判定某个任务是否完成
# print(task1.done())
# # print(task2.cancel())  # 任务在执行中或执行完成是无法取消的
# time.sleep(3)
# print(task1.done())
#
# # result方法可以获取task的执行结果
# print(task1.result())  # 阻塞